using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Drawing;
using System.Threading.Tasks;
using System.Drawing.Drawing2D;

namespace IpMacConfiguratorFramework
{
    public partial class MainForm : Form
    {
        private const string CsvFileName = "ip_mac_table.csv";
        private List<IpMacConfiguratorFramework.NetworkHelper.NetworkAdapterInfo> adapters;
        private System.Windows.Forms.Timer progressTimer = new System.Windows.Forms.Timer();
        private int progressPos = 0; // 方形边框动画进度
        private bool isProgressActive = false;

        public MainForm()
        {
            InitializeComponent();
            // 将加载逻辑移至 MainForm_Load 事件
            // IpMacConfiguratorFramework.IpMacTable.LoadFromResource();
            // LoadAdapters();
            // comboBoxAdapters.SelectedIndexChanged += ComboBoxAdapters_SelectedIndexChanged;
            richTextBoxLog.Font = new Font("微软雅黑", 10.5f, FontStyle.Regular);
            progressTimer.Interval = 50; // 动画更慢
            progressTimer.Tick += ProgressTimer_Tick;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // 在窗体加载时执行初始化逻辑
            IpMacConfiguratorFramework.IpMacTable.LoadFromResource();
            LoadAdapters();

            // 设置日志文本框使用等宽字体以便对齐
            richTextBoxLog.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        }

        private void LoadAdapters()
        {
            adapters = IpMacConfiguratorFramework.NetworkHelper.GetWiredAdapters();
            comboBoxAdapters.Items.Clear();
            foreach (var adapter in adapters)
            {
                comboBoxAdapters.Items.Add($"{adapter.Name} - {adapter.Description}");
            }
            if (comboBoxAdapters.Items.Count > 0)
            {
                comboBoxAdapters.SelectedIndex = 0;
                // 显示第一个网卡的当前IP
                ShowCurrentAdapterInfo(0);
            }
        }

        private void ComboBoxAdapters_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxAdapters.SelectedIndex < 0) return;
            ShowCurrentAdapterInfo(comboBoxAdapters.SelectedIndex);
        }

        private void ShowCurrentAdapterInfo(int index)
        {
            if (index < 0 || index >= adapters.Count) return;

            var adapter = adapters[index];
            // 使用 NetworkHelper 中的 FormatMac
            textBoxMac.Text = IpMacConfiguratorFramework.NetworkHelper.FormatMac(adapter.MacAddress);

            // 显示当前网卡的IP信息到只读文本框
            textBoxCurrentIp.Text = adapter.IpAddress;
            textBoxCurrentMask.Text = adapter.SubnetMask;
            textBoxCurrentGateway.Text = adapter.Gateway;
            textBoxCurrentDns.Text = adapter.DnsAddresses;

            // 清空可编辑文本框和日志区
            textBoxIp.Text = "";
            textBoxMask.Text = "";
            textBoxGateway.Text = "";
            textBoxDns.Text = "";
            richTextBoxLog.Clear(); // ShowCurrentAdapterInfo的职责是清空并显示当前状态

            var entry = IpMacConfiguratorFramework.IpMacTable.FindByMac(IpMacConfiguratorFramework.NetworkHelper.FormatMac(adapter.MacAddress));

            if (entry != null)
            {
                textBoxType.Text = entry.Type;
                textBoxDepartment.Text = entry.Department;
                textBoxUser.Text = entry.User;

                // 获取规划的子网掩码、网关和DNS
                string plannedMask = entry.Type == "内网" ? "255.255.254.0" : "255.255.255.0";
                string plannedGateway = entry.Type == "内网" ? "10.11.93.254" : "192.168.2.1";
                string plannedDns = entry.Type == "内网" ? "10.10.2.53,10.10.2.54" : "211.138.91.1,114.114.114.114";

                textBoxIp.Text = entry.Ip;
                textBoxMask.Text = plannedMask;
                textBoxGateway.Text = plannedGateway;
                textBoxDns.Text = plannedDns;

                bool ipMatch = adapter.IpAddress.Equals(entry.Ip, StringComparison.OrdinalIgnoreCase);
                bool maskMatch = adapter.SubnetMask.Equals(plannedMask, StringComparison.OrdinalIgnoreCase);
                bool gatewayMatch = adapter.Gateway.Equals(plannedGateway, StringComparison.OrdinalIgnoreCase);
                bool dnsMatch = plannedDns.Split(',').All(d => adapter.DnsAddresses.Contains(d));

                // 日志区输出
                richTextBoxLog.Clear();
                AppendLog("------ 当前状态信息 ------");
                AppendLog("您当前电脑网卡物理地址在公司规划范围", "green");
                AppendLog("");
                AppendLog($"业务范围：{entry.Type}");
                AppendLog($"所属部门：{entry.Department}");
                AppendLog($"使用人：{entry.User}");
                AppendLog("");
                if (ipMatch && maskMatch && gatewayMatch && dnsMatch)
                {
                    AppendLog("当前IP地址信息符合规划信息，无需修改。");
                }
                else
                {
                    AppendLog("当前IP地址信息不符合规划设置，应当设置为：", "red");
                    AppendLog($"I P 地  址：  {entry.Ip}");
                    AppendLog($"子网掩码：  {plannedMask}");
                    AppendLog($"网关地址：  {plannedGateway}");
                    string[] dnsArray = plannedDns.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    if (dnsArray.Length > 0)
                    {
                        AppendLog($"首选DNS：   {dnsArray[0].Trim()}");
                        if (dnsArray.Length > 1)
                        {
                            AppendLog($"备用DNS：   {dnsArray[1].Trim()}");
                        }
                    }
                }
            }
            else // 未匹配
            {
                textBoxType.Text = "未匹配";
                textBoxDepartment.Text = "";
                textBoxUser.Text = "";
                richTextBoxLog.Clear();
                AppendLog("------ 当前状态信息 ------");
                AppendLog("您当前网卡物理地址不在规化范围，无法进行内网或外网连接应用。", "red");
            }
        }

        private void buttonApply_Click(object sender, EventArgs e)
        {
            // 清空日志区，开始新的操作日志
            richTextBoxLog.Clear();

            // 声明returnValue变量
            uint returnValue; 

            // 获取当前选中的网卡适配器
            if (comboBoxAdapters.SelectedIndex < 0 || comboBoxAdapters.SelectedIndex >= adapters.Count)
            {
                richTextBoxLog.AppendText("请先选择一个有效的网卡。\r\n");
                return;
            }
            var selectedAdapter = adapters[comboBoxAdapters.SelectedIndex];

            // 获取用户输入的信息
            string plannedIp = textBoxIp.Text.Trim();
            string plannedMask = textBoxMask.Text.Trim();
            string plannedGateway = textBoxGateway.Text.Trim();
            string plannedDns = textBoxDns.Text.Trim();

            // 基本输入校验
            if (string.IsNullOrEmpty(plannedIp) || string.IsNullOrEmpty(plannedMask))
            {
                richTextBoxLog.AppendText("IP地址和子网掩码不能为空。\r\n");
                return;
            }

            // 使用netsh命令设置网络配置
            try
            {
                richTextBoxLog.AppendText($"正在尝试设置 '{selectedAdapter.Description}' 的网络配置...\r\n");

                // --- 使用 netsh 命令设置 IP, 子网掩码, 网关 ---
                string setAddressCommand = $"interface ip set address name=\"{selectedAdapter.Name}\" static {plannedIp} {plannedMask}";
                if (!string.IsNullOrEmpty(plannedGateway))
                {
                    setAddressCommand += $" {plannedGateway} 1"; // 添加网关和跃点数
                }

                System.Diagnostics.Process processSetAddress = new System.Diagnostics.Process();
                processSetAddress.StartInfo.FileName = "netsh.exe";
                processSetAddress.StartInfo.Arguments = setAddressCommand;
                processSetAddress.StartInfo.UseShellExecute = false;
                processSetAddress.StartInfo.RedirectStandardOutput = true;
                processSetAddress.StartInfo.RedirectStandardError = true; // 也重定向错误输出
                processSetAddress.StartInfo.CreateNoWindow = true;
                processSetAddress.StartInfo.StandardOutputEncoding = System.Text.Encoding.GetEncoding("GBK");
                processSetAddress.StartInfo.StandardErrorEncoding = System.Text.Encoding.GetEncoding("GBK"); // 设置错误输出编码
                processSetAddress.Start();
                processSetAddress.WaitForExit();
                string setAddressOutput = processSetAddress.StandardOutput.ReadToEnd();
                string setAddressError = processSetAddress.StandardError.ReadToEnd(); // 读取错误输出
                int exitCode = processSetAddress.ExitCode; // 获取退出代码

                if (!string.IsNullOrEmpty(setAddressError))
                {
                     richTextBoxLog.AppendText($"netsh IP/Mask/Gateway 设置错误输出:\r\n{setAddressError}\r\n");
                }

                // 根据netsh的退出代码判断是否成功
                if (exitCode == 0) // 通常0表示成功
                {
                    richTextBoxLog.AppendText("IP地址、子网掩码和网关设置成功。\r\n");

                    // 设置DNS
                    if (!string.IsNullOrEmpty(plannedDns))
                    {
                        string[] dnsServers = plannedDns.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).ToArray();
                        if (dnsServers.Length > 0)
                        {
                            // 使用netsh命令设置DNS服务器
                            try
                            {
                                // 设置主DNS
                                string setPrimaryDnsCommand = $"interface ip set dns name=\"{selectedAdapter.Name}\" static {dnsServers[0]} primary";
                                System.Diagnostics.Process processSetPrimary = new System.Diagnostics.Process();
                                processSetPrimary.StartInfo.FileName = "netsh.exe";
                                processSetPrimary.StartInfo.Arguments = setPrimaryDnsCommand;
                                processSetPrimary.StartInfo.UseShellExecute = false;
                                processSetPrimary.StartInfo.RedirectStandardOutput = true;
                                processSetPrimary.StartInfo.CreateNoWindow = true;
                                // 设置输出编码为GBK
                                processSetPrimary.StartInfo.StandardOutputEncoding = System.Text.Encoding.GetEncoding("GBK");
                                processSetPrimary.Start();
                                processSetPrimary.WaitForExit();
                                string setPrimaryOutput = processSetPrimary.StandardOutput.ReadToEnd();

                                // 如果有备用DNS，则添加
                                if (dnsServers.Length > 1)
                                {
                                    string addSecondaryDnsCommand = $"interface ip add dns name=\"{selectedAdapter.Name}\" {dnsServers[1]} index=2";
                                    System.Diagnostics.Process processAddSecondary = new System.Diagnostics.Process();
                                    processAddSecondary.StartInfo.FileName = "netsh.exe";
                                    processAddSecondary.StartInfo.Arguments = addSecondaryDnsCommand;
                                    processAddSecondary.StartInfo.UseShellExecute = false;
                                    processAddSecondary.StartInfo.RedirectStandardOutput = true;
                                    processAddSecondary.StartInfo.CreateNoWindow = true;
                                    // 设置输出编码为GBK
                                    processAddSecondary.StartInfo.StandardOutputEncoding = System.Text.Encoding.GetEncoding("GBK");
                                    processAddSecondary.Start();
                                    processAddSecondary.WaitForExit();
                                    string addSecondaryOutput = processAddSecondary.StandardOutput.ReadToEnd();
                                }

                                richTextBoxLog.AppendText("DNS服务器设置完成。\r\n");

                            }
                            catch (Exception netshEx)
                            {
                                richTextBoxLog.AppendText($"执行netsh命令设置DNS时发生错误: {netshEx.Message}\r\n");
                            }

                        }
                        else
                        {
                            richTextBoxLog.AppendText("计划DNS字符串解析后没有有效的服务器地址。\r\n");
                        }
                    }
                    else
                    {
                         richTextBoxLog.AppendText("DNS服务器未设置（输入为空）。\r\n");
                    }

                    richTextBoxLog.AppendText("所有请求的设置操作已完成。\r\n");

                     // 添加操作完成的总结信息
                     richTextBoxLog.AppendText("\r\n------ 操作结果 ------\r\n");
                     richTextBoxLog.AppendText("网络配置应用尝试完成。请查看当前信息是否已更新。\r\n");

                     // 重新加载适配器信息并更新当前显示
                     LoadAdapters(); // 重新获取所有适配器的最新信息
                     // Note: LoadAdapters() already sets selected index and triggers ShowCurrentAdapterInfo
                     // We just need to ensure the correct adapter is selected after reloading
                     // The following logic is complex and might not be necessary if LoadAdapters() handles selection correctly
                     // var updatedAdapters = IpMacConfiguratorFramework.NetworkHelper.GetWiredAdapters();
                     // var reSelectedAdapter = updatedAdapters.FirstOrDefault(a => a.MacAddress.Equals(selectedAdapter.MacAddress, StringComparison.OrdinalIgnoreCase));

                     // if (reSelectedAdapter != null)
                     // {
                     //     var indexToUpdate = adapters.FindIndex(a => a.MacAddress.Equals(reSelectedAdapter.MacAddress, StringComparison.OrdinalIgnoreCase));
                     //     if (indexToUpdate >= 0)
                     //     {
                     //         adapters[indexToUpdate] = reSelectedAdapter;
                     //         int newSelectedIndex = comboBoxAdapters.FindStringExact($"{reSelectedAdapter.Name} - {reSelectedAdapter.Description}");
                     //         if (newSelectedIndex >= 0)
                     //         {
                     //             comboBoxAdapters.SelectedIndex = newSelectedIndex;
                     //         }
                     //     }
                     // }
                     // ShowCurrentAdapterInfo(comboBoxAdapters.SelectedIndex); // LoadAdapters() already calls this

                }
                else // IP/Mask 设置失败
                {
                    richTextBoxLog.AppendText($"IP地址和子网掩码设置失败，返回代码：{exitCode}。\r\n");
                     // 对于其他设置（网关、DNS），如果IP/Mask设置失败，也不应该尝试。

                     // 添加操作失败的总结信息
                     richTextBoxLog.AppendText("\r\n------ 操作结果 ------\r\n");
                     richTextBoxLog.AppendText("网络配置应用失败。请检查日志和权限。\r\n");
                }

            }
            catch (ManagementException mex)
            {
                 // 捕获WMI相关的异常，例如权限问题
                richTextBoxLog.AppendText($"设置网络配置时发生WMI错误：{mex.Message}\r\n");
                richTextBoxLog.AppendText("请确保您以管理员身份运行本程序。\r\n");

                 // 添加操作失败的总结信息
                 richTextBoxLog.AppendText("\r\n------ 操作结果 ------\r\n");
                 richTextBoxLog.AppendText("网络配置应用失败：发生WMI错误。\r\n");
            }
            catch (Exception ex)
            {
                // 捕获其他可能的异常
                richTextBoxLog.AppendText($"设置网络配置时发生错误：{ex.Message}\r\n");

                 // 添加操作失败的总结信息
                 richTextBoxLog.AppendText("\r\n------ 操作结果 ------\r\n");
                 richTextBoxLog.AppendText("网络配置应用失败：发生未知错误。\r\n");
            }
        }

        private void ProgressTimer_Tick(object sender, EventArgs e)
        {
            int w = this.ClientSize.Width - 4;
            int h = this.ClientSize.Height - 4;
            int totalLen = w * 2 + h * 2;
            progressPos = (progressPos + 1) % totalLen; // 步长为1，动画更慢更匀速
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (isProgressActive)
            {
                int margin = 2;
                int w = this.ClientSize.Width - margin * 2;
                int h = this.ClientSize.Height - margin * 2;
                int totalLen = w * 2 + h * 2;

                // 1. 绘制完整彩虹边框
                for (int i = 0; i < totalLen; i++)
                {
                    Point pt1, pt2;
                    GetBorderPointPair(i, out pt1, out pt2, w, h, margin);
                    Color color = GetRainbowColor((float)i / totalLen);
                    using (Pen pen = new Pen(color, 3))
                    {
                        e.Graphics.DrawLine(pen, pt1, pt2);
                    }
                }

                // 2. 绘制动态炫彩进度条
                int len = 60; // 动态段长度
                for (int i = 0; i < len; i++)
                {
                    int p = (progressPos + i) % totalLen;
                    Point pt1, pt2;
                    GetBorderPointPair(p, out pt1, out pt2, w, h, margin);
                    Color color = GetRainbowColor((float)p / totalLen);
                    using (Pen pen = new Pen(color, 7)) // 更粗
                    {
                        e.Graphics.DrawLine(pen, pt1, pt2);
                    }
                }
            }
        }

        private Color GetRainbowColor(float t)
        {
            // t: 0~1
            int r = (int)(Math.Sin(2 * Math.PI * t) * 127 + 128);
            int g = (int)(Math.Sin(2 * Math.PI * t + 2 * Math.PI / 3) * 127 + 128);
            int b = (int)(Math.Sin(2 * Math.PI * t + 4 * Math.PI / 3) * 127 + 128);
            return Color.FromArgb(r, g, b);
        }

        private void GetBorderPointPair(int p, out Point pt1, out Point pt2, int w, int h, int margin)
        {
            if (p < w) // 上边
            {
                pt1 = new Point(margin + p, margin);
                pt2 = new Point(margin + p + 1, margin);
            }
            else if (p < w + h) // 右边
            {
                pt1 = new Point(w + margin, margin + (p - w));
                pt2 = new Point(w + margin, margin + (p - w) + 1);
            }
            else if (p < w * 2 + h) // 下边
            {
                pt1 = new Point(w + margin - (p - w - h), h + margin);
                pt2 = new Point(w + margin - (p - w - h) - 1, h + margin);
            }
            else // 左边
            {
                pt1 = new Point(margin, h + margin - (p - w * 2 - h));
                pt2 = new Point(margin, h + margin - (p - w * 2 - h) - 1);
            }
        }

        private async void buttonCheck_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBoxGateway.Text))
            {
                AppendLog("错误：网关地址为空，请先选择网卡", "red");
                return;
            }
            AppendLog("正在检测网关连接状态...");
            string gateway = textBoxGateway.Text.Trim();

            // 启动动画
            isProgressActive = true;
            progressTimer.Start();
            this.Invalidate();

            // 异步执行网络检测
            var result = await Task.Run(() => {
                bool isConnected = NetworkHelper.CheckGatewayConnection(gateway, out string message);
                return (isConnected, message);
            });

            // 停止动画
            isProgressActive = false;
            progressTimer.Stop();
            this.Invalidate();

            AppendLog(result.message, result.isConnected ? "green" : "red");
            if (result.isConnected)
            {
                AppendLog("网关连接正常，可以正常使用！", "green");
                buttonCheck.BackColor = Color.Green;
                buttonCheck.ForeColor = Color.White;
            }
            else
            {
                AppendLog("警告：网关连接异常，请检查网络连接或联系管理员", "red");
                buttonCheck.BackColor = Color.Red;
                buttonCheck.ForeColor = Color.White;
            }
        }

        // 添加日志的辅助方法
        private void AppendLog(string message, string highlight = null)
        {
            if (richTextBoxLog.InvokeRequired)
            {
                richTextBoxLog.Invoke(new Action(() => AppendLog(message, highlight)));
                return;
            }
            // 确保光标在末尾
            richTextBoxLog.SelectionStart = richTextBoxLog.TextLength;
            richTextBoxLog.SelectionLength = 0;

            if (highlight == "green")
            {
                richTextBoxLog.SelectionColor = Color.Green;
                richTextBoxLog.SelectionFont = new Font("微软雅黑", 10.5f, FontStyle.Bold);
            }
            else if (highlight == "red")
            {
                richTextBoxLog.SelectionColor = Color.Red;
                richTextBoxLog.SelectionFont = new Font("微软雅黑", 10.5f, FontStyle.Bold);
            }
            else
            {
                richTextBoxLog.SelectionColor = Color.Black;
                richTextBoxLog.SelectionFont = new Font("微软雅黑", 10.5f, FontStyle.Regular);
            }
            richTextBoxLog.AppendText(message + Environment.NewLine);
            richTextBoxLog.ScrollToCaret();
        }
    }
} 